package run;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.messaging.simp.stomp.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.socket.WebSocketHttpHeaders;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;

import javax.security.auth.Subject;
import java.lang.reflect.Type;
import java.security.Principal;

@Slf4j
@SpringBootTest(classes = StartUpForStompSlaveClient.Dummy.class,
        webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class StartUpForStompSlaveClient {

    public StartUpForStompSlaveClient(){}
    @Autowired
    GenericApplicationContext applicationContext;

    @Import(value = {StartUpForStompSlaveClient.class,com.SpringApplication.class})
    @Configuration
    public  class Dummy {
    }
    Object lock = new Object();
    // get user-registry ,


    @Test
    public void makeUpClient() throws InterruptedException {
        log.info("===========initials==================");
        WebSocketClient webSocketClient = new StandardWebSocketClient();
        WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
        stompClient.setMessageConverter(new StringMessageConverter());
        ThreadPoolTaskScheduler bean = applicationContext.getBean(ThreadPoolTaskScheduler.class);
        Assertions.assertNotNull(bean);
        stompClient.setTaskScheduler(bean);
        String url = "ws://127.0.0.1:8083/portfolio";
//
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("Cookie","Idea-8296eb30=d86bdee7-e00f-48c3-83fe-e0b84df74a4a; csrftoken=0LhpmoWVdWhTcxNSA2r5sEhs2UZeLlAYelJm4l6apaQ0dZbxoXNlACspJWWG7u4S; Pastease.passive.chance.kfzz9br7dC3Qwzl=chance77.0; Pastease.passive.activated.kfzz9br7dC3Qwzl=0; _ga=GA1.1.1398574246.1660881221; SESSION=715fc843-02f0-4ab5-afdd-6307b826fc99; JSESSIONID=015979C4F1B1F40531370234FC3A9FA3");
        WebSocketHttpHeaders webSocketHttpHeaders = new WebSocketHttpHeaders(httpHeaders);

        StompHeaders stompHeaders = new StompHeaders();
        stompHeaders.set("Cookie","Idea-8296eb30=d86bdee7-e00f-48c3-83fe-e0b84df74a4a; csrftoken=0LhpmoWVdWhTcxNSA2r5sEhs2UZeLlAYelJm4l6apaQ0dZbxoXNlACspJWWG7u4S; Pastease.passive.chance.kfzz9br7dC3Qwzl=chance77.0; Pastease.passive.activated.kfzz9br7dC3Qwzl=0; _ga=GA1.1.1398574246.1660881221; SESSION=715fc843-02f0-4ab5-afdd-6307b826fc99; JSESSIONID=015979C4F1B1F40531370234FC3A9FA3");
        stompHeaders.setHeartbeat(new long[]{0,0});

        StompSessionHandler sessionHandler = new MyStompSessionHandler();
        ListenableFuture<StompSession> connect = stompClient.connect(url,webSocketHttpHeaders,stompHeaders, sessionHandler);

        connect.addCallback((StompSession session)->{
            log.info("session:{}",session.getSessionId());
        },(Throwable throwable)->{
            log.error("throwable:{}",throwable);
        });

        synchronized (lock){
            lock.wait();;
        }
    }

    public class MyStompSessionHandler extends StompSessionHandlerAdapter {

        @Override
        public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
//            StompHeaders stompHeaders = new StompHeaders();
//            stompHeaders.setDestination("/app/info");
//            session.send(stompHeaders,"helloworld!!!");
//
//            stompHeaders.setDestination("/topic/info");
//            Assertions.assertTrue(session instanceof DefaultStompSession);
//
//            StompSession.Subscription subscribe = session.subscribe(stompHeaders, new StompFrameHandler() {
//                @Override
//                public Type getPayloadType(StompHeaders headers) {
//
//                    return String.class;
//                }
//
//                @Override
//                public void handleFrame(StompHeaders headers, Object payload) {
//                    log.info("msg:{},{}", headers.getDestination(), payload.toString());
//                }
//            });
//            StompHeaders subscriptionHeaders = subscribe.getSubscriptionHeaders();
//            String subscriptionId = subscribe.getSubscriptionId();
//            log.info("{},{}",subscriptionHeaders.getId(),subscriptionId);
            // use the sockjs send msg ,

//            StompSession.Subscription subscribe2 = session.subscribe("ActiveMQ.Advisory.Consumer.Topic.app/subscribe/foo", new StompFrameHandler() {
//                @Override
//                public Type getPayloadType(StompHeaders headers) {
//                    return String.class;
//                }
//
//                @Override
//                public void handleFrame(StompHeaders headers, Object payload) {
//                    log.info("msg:{},{}", headers.getDestination(), payload.toString());
//                }
//            });

            // headers.setSessionId(sessionId);
            StompHeaders stompHeaders = new StompHeaders();
            stompHeaders.setDestination("/user/joe/queue/foo");

            StompSession.Receiptable send = session.send(stompHeaders, "helloworld!!!");
            log.info("ReceiptId:{},sessionId:{}",send.getReceiptId(),session.getSessionId());;
            String dest=String.format("/queue/foo-user%s", "4d5226ed-699a-136c-3edb-3bdd363dcdb7");

            StompSession.Subscription subscribe3 = session.subscribe(dest, new StompFrameHandler() {
                @Override
                public Type getPayloadType(StompHeaders headers) {
                    return String.class;
                }

                @Override
                public void handleFrame(StompHeaders headers, Object payload) {
                    log.info("msg:{},{}", headers.getDestination(), payload.toString());
                }
            });
            log.info("{},{}",subscribe3.getReceiptId(),subscribe3.getSubscriptionId());

        }
    }
    @NoArgsConstructor
    @AllArgsConstructor
    public class CustomPrincipal implements Principal {
        private String name;

        @Override
        public String getName() {
            return name;
        }

        @Override
        public boolean implies(Subject subject) {
            return Principal.super.implies(subject);
        }
    }

    @Test
    public void verify() throws InterruptedException {
        synchronized (lock) {
            lock.wait();
        }
    }

}
